package siedler.GUI.other;

import java.io.Serializable;

public class Coordinate implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public int x1,y1,x2,y2;
	
	/**
	 * Empty Constructor (all zero)
	 */
	public Coordinate(){
		this(0,0,0,0);
	}
	/**
	 * Point constructor
	 * @param x
	 * @param y
	 */
	public Coordinate(int x,int y){
		this(x,y,x,y);
	}
	/**
	 * Point constructor
	 * @param x
	 * @param y
	 */
	public Coordinate(double x,double y){
		this((int)x,(int)y,(int)x,(int)y);
	}
	/**
	 * Constructor with radius (x/y is Center)
	 * @param x
	 * @param y
	 * @param r
	 */
	public Coordinate(int x,int y, int r){
		this(x-r,y-r,x+r,y+r);
	}
	/**
	 * Full Constructor
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 */
	public Coordinate(int x1,int y1,int x2,int y2){
		this.x1 = x1;
		this.y1 = y1;
		this.x2 = x2;
		this.y2 = y2;
	}
	
	/**
	 * copy
	 * @return a copy of this coordinate
	 */
	public Coordinate copy(){
		Coordinate c = new Coordinate(x1,y1,x2,y2);
		return c;
	}
	
	/**
	 * adds x/y to all coordinates adequately.
	 * @param x
	 * @param y
	 * @return this
	 */
	public Coordinate add(int x, int y){
		x1 +=x;
		y1 +=y;
		x2 +=x;
		y2 +=y;
		return this;
	}
	/**
	 * Adds c to this coordinate.
	 * @param c
	 * @return this
	 */
	public Coordinate add(Coordinate c){
		x1 +=c.x1;
		y1 +=c.y1;
		x2 +=c.x2;
		y2 +=c.y2;
		return this;
	}
	
	/**
	 * contains
	 * @param x
	 * @param y
	 * @return true if this coordinate is equal to x/y or surrounds x/y
	 */
	public boolean contains(int x, int y){
		boolean con = x>=x1 && x<=x2 && y>=y1 && y<=y2;
		return con;
	}
	public boolean contains(Coordinate c){
		boolean con = contains(c.x1,c.y1) && contains(c.x2,y2);
		return con;
	}
	
	/**
	 * Set start coordinates
	 * @param x1
	 * @param y1
	 */
	public void set1(int x1, int y1){
		this.x1=x1; this.y1=y1;
	}
	/**
	 * Set final coordinates
	 * @param x2
	 * @param y2
	 */
	public void set2(int x2, int y2){
		this.x2=x2; this.y2=y2;
	}
	
	/**
	 * middle(c)
	 * @param c
	 * @return a new coordinate (point) with x/y in the average of 'c'.
	 */
	public static Coordinate middle(Coordinate c){
		return new Coordinate( (c.x1+c.x2)/2, (c.y1+c.y2)/2 );
	}
	/**
	 * middle(c1, c2)
	 * @param c1
	 * @param c2
	 * @return a new coordinate (rectangle) with each x_n/y_n as the average of the respective x_ns/y_ns
	 */
	public static Coordinate middle(Coordinate c1, Coordinate c2){
		return new Coordinate( (c1.x1+c2.x1)/2, (c1.y1+c2.y1)/2, (c1.x2+c2.x2)/2, (c1.y2+c2.y2)/2 );
	}
	
	/**
	 * Sorting Rules:
	 * 		x1 <= x2
	 * 		y1 <= y2
	 * @return this
	 */
	public Coordinate sortHighLow(){
		//Out.pl("before: " + this);
		if(x1>x2){
			int tmp = x1;
			x1 = x2;
			x2 = tmp;
		}
		if(y1>y2){
			int tmp = y1;
			y1 = y2;
			y2 = tmp;
		}
		//Out.pl("After: " + this);
		return this;
	}
	
	/**
	 * getWidth
	 * @param min - can be specified as minimal value wished for width
	 * @return width OR min
	 */
	public int getWidth(int min){
		int w = x2-x1;
		if(w<0) 	w*=-1;
		if(w<min) 	w=min;
		return w;
	}
	
	/**
	 * getHeight
	 * @param min - can be specified as minimal value wished for height
	 * @return height OR min
	 */
	public int getHeight(int min){
		int h = y2-y1;
		if(h<0) 	h*=-1;
		if(h<min) 	h=min;
		return h;
	}
	
	@Override
	public String toString(){
		
		if(x1==x2 && y1==y2){
			return ""+x1+"/"+y1+"";
		}
		else{
			return ""+x1+"/"+y1+" to "+x2+"/"+y2+"";
		}
	}
}
